package com.shopping.mall.core.module.order.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shopping.mall.auth.utils.UserUtils;
import com.shopping.mall.base.state.OrderState;
import com.shopping.mall.base.util.StringUtil;
import com.shopping.mall.core.module.cart.entity.Cart;
import com.shopping.mall.core.module.cart.entity.CartList;
import com.shopping.mall.core.module.cart.service.CartService;
import com.shopping.mall.core.module.freight.mapper.FreightMapper;
import com.shopping.mall.core.module.goods.mapper.GoodsMapper;
import com.shopping.mall.core.module.goodsSpecification.mapper.GoodsSpecificationMapper;
import com.shopping.mall.core.module.goodsSpecification.mapper.NumPriceMapper;
import com.shopping.mall.core.module.goodsSpecification.service.GoodsSpecificationService;
import com.shopping.mall.core.module.order.entity.GoodOrder;
import com.shopping.mall.core.module.order.entity.OrderGood;
import com.shopping.mall.core.module.order.entity.Order;
import com.shopping.mall.core.module.order.mapper.OrderGoodMapper;
import com.shopping.mall.core.module.order.mapper.OrderMapper;
import com.shopping.mall.core.module.order.service.MailService;
import com.shopping.mall.core.module.order.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping.mall.base.http.ResponseState;
import com.shopping.mall.base.http.Result;
import com.shopping.mall.base.util.WrapperUtils;
import com.shopping.mall.core.module.order.service.StockService;
import com.shopping.mall.core.module.paypal.service.impl.PaymentServiceImpl;
import com.shopping.mall.core.module.saleData.entity.SaleData;
import com.shopping.mall.core.module.saleData.service.SaleDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * <p>
 *  Order服务实现类
 * </p>
 *
 * @author zzy
 * @since 2021-08-16
 */
@Validated
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {


    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderGoodMapper orderGoodMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GoodsSpecificationMapper specificationMapper;

    @Autowired
    private NumPriceMapper numPriceMapper;

    @Autowired
    private FreightMapper freightMapper;

    @Autowired
    private CartService cartService;

    @Autowired
    private SaleDataService saleDataService;

    @Autowired
    private GoodsSpecificationService goodsSpecificationService;

    @Autowired
    private StockService stockService;

    @Autowired
    private PaymentServiceImpl paymentService;

    @Override
    public IPage<Order> getOrderPage(Integer current, Integer size, Order order) {
        QueryWrapper<Order> queryWrapper = WrapperUtils.queryWrapper(order);
        queryWrapper.orderByDesc("create_at");
        Page<Order>  orderPage= new Page<>(current,size);
        IPage<Order> orderIPage = orderMapper.selectPage(orderPage, queryWrapper);
        return orderIPage;
    }

    @Autowired
    private MailService mailService;

    /**
     * 查询所有
     * @param order：筛选条件
     * @return List<Order>
     */
    @Override
    public List<Order> getAll(Order order){
        QueryWrapper<Order> orderQueryWrapper=WrapperUtils.queryWrapper(order);
        return orderMapper.selectList(orderQueryWrapper);
    }

    /**
     * 通过id删除
     * @param id：orderId
     * @return Result<Object>
     */
    @Override
    public Result<Object> deleteById(String id){
        Order order=orderMapper.selectById(id);
        if(order==null){
            return Result.error(ResponseState.TARGET_NOT_EXIST.getValue(), ResponseState.TARGET_NOT_EXIST.getMessage());
        }
        orderMapper.deleteById(id);
        return Result.OK();
    }

    /**
    * 批量删除
    * @param ids：id列表
    * @return Result<Object>
    */
    @Override
    public Result<Object> batchDelete(List<String> ids){
        UpdateWrapper<Order> updateWrapper=new UpdateWrapper<>();
        updateWrapper.in("id",ids);
        orderMapper.delete(updateWrapper);
        return Result.OK();
    }

    /**
     * 创建订单
     * @param order：订单信息
     * @return Order
     */
    @Override
    public Result<Order> createOrder(Order order) {
        CartList cartList=cartService.getAll();
        if(cartList.getCartList()==null||cartList.getCartList().size()==0){
            return Result.error(ResponseState.GOODS_IS_NULL.getValue(),ResponseState.GOODS_IS_NULL.getMessage());
        }
        order.setCart(cartList);
        List<Cart> buyGoods=new ArrayList<>();
        for(Cart cart:cartList.getCartList()){
            if(cart.getLaterBuy()==1){
                buyGoods.add(cart);
            }
        }
        order.setGoods(JSON.toJSONString(buyGoods));
        return Result.OK(order);
    }


    @Transactional
    @Override
    public Result<Object> add(Order order) {
        CartList cartList=cartService.getAll();
        if(cartList.getCartList()==null||cartList.getCartList().size()==0){
            return Result.error(ResponseState.GOODS_IS_NULL.getValue(),ResponseState.GOODS_IS_NULL.getMessage());
        }
        order.setCart(cartList);
        order.setUserId(UserUtils.getLoginUserId());
        order.setOrderNumber(String.valueOf(new Date().getTime()));
        order.setState(OrderState.START.getValue());
        List<Cart> buyGoods=new ArrayList<>();
        for(Cart cart:cartList.getCartList()){
            if(cart.getLaterBuy()==1){
                buyGoods.add(cart);
            }
        }
        order.setGoods(JSON.toJSONString(buyGoods));
        orderMapper.insert(order);
        return Result.OK(getById(order.getId()));
    }

    @Override
    public Result<Object> payOrder(Order order) {
        Order oldOrder=orderMapper.selectById(order.getId());
        if(oldOrder==null){
            return Result.error(ResponseState.ORDER_NOT_EXIST.getValue(),ResponseState.ORDER_NOT_EXIST.getMessage());
        }
        if(!oldOrder.getUserId().equals(UserUtils.getLoginUserId())){
            return Result.error(ResponseState.ERROR.getValue(), ResponseState.ERROR.getMessage());
        }
        if(oldOrder.getState()!=OrderState.START.getValue()){
            return Result.error(ResponseState.ORDER_NOT_MATCH.getValue(),ResponseState.ORDER_NOT_MATCH.getMessage());
        }
        oldOrder.setState(OrderState.COPY_SUCCESS.getValue());
        orderMapper.updateById(oldOrder);
        saleDataService.addOrder(oldOrder);
        return Result.OK(oldOrder);
    }

    /**
     * 取消订单
     */
    @Transactional
    @Override
    public Result<Object> cancelOrder(String orderId) {
        Order oldOrder=orderMapper.selectById(orderId);
        if(oldOrder==null){
            return Result.error(ResponseState.ORDER_NOT_EXIST.getValue(),ResponseState.ORDER_NOT_EXIST.getMessage());
        }
//        if(!oldOrder.getUserId().equals(UserUtils.getLoginUserId())){
//            return Result.error(ResponseState.ERROR.getValue(), ResponseState.ERROR.getMessage());
//        }
        if(oldOrder.getState()!=OrderState.START.getValue()&&oldOrder.getState()!=OrderState.COPY_SUCCESS.getValue()){
            return Result.error(ResponseState.ORDER_NOT_MATCH.getValue(),ResponseState.ORDER_NOT_MATCH.getMessage());
        }
        //订单是否已支付，已支付需审核
        if(oldOrder.getState()==OrderState.COPY_SUCCESS.getValue()){
//            return paymentService.refund(oldOrder);
            oldOrder.setState(OrderState.CHECK.getValue());
        }else{
            oldOrder.setState(OrderState.ORDER_CANCEL.getValue());
        }
        orderMapper.updateById(oldOrder);
        stockService.addStock(oldOrder.getGoods());
        return Result.OK(oldOrder);
    }


    @Override
    public Result<Object> sendOrder(Order order) {
        Order oldOrder=orderMapper.selectById(order.getId());
        if(oldOrder==null){
            return Result.error(ResponseState.ORDER_NOT_EXIST.getValue(),ResponseState.ORDER_NOT_EXIST.getMessage());
        }
        if(oldOrder.getState()!=OrderState.COPY_SUCCESS.getValue()){
            return Result.error(ResponseState.ORDER_NOT_MATCH.getValue(),ResponseState.ORDER_NOT_MATCH.getMessage());
        }
        oldOrder.setState(OrderState.GOOD_HAS_SEND.getValue());
        orderMapper.updateById(oldOrder);
        return Result.OK(oldOrder);
    }

    @Transactional
    @Override
    public Result<Object> finishOrder(Order order) {
        Order oldOrder=orderMapper.selectById(order.getId());
        if(oldOrder==null){
            return Result.error(ResponseState.ORDER_NOT_EXIST.getValue(),ResponseState.ORDER_NOT_EXIST.getMessage());
        }
        if(!oldOrder.getUserId().equals(UserUtils.getLoginUserId())){
            return Result.error(ResponseState.ERROR.getValue(), ResponseState.ERROR.getMessage());
        }
        if(oldOrder.getState()!=OrderState.GOOD_HAS_SEND.getValue()){
            return Result.error(ResponseState.ORDER_NOT_MATCH.getValue(),ResponseState.ORDER_NOT_MATCH.getMessage());
        }
        oldOrder.setFinishWay(1);
        oldOrder.setState(OrderState.ORDER_FINISH.getValue());
        oldOrder.setFinishAt(new Timestamp(new Date().getTime()));
        orderMapper.updateById(oldOrder);
        mailService.finishOrder(oldOrder);
        return Result.OK(oldOrder);
    }

    @Override
    public Result<Object> delivery(OrderGood orderGood) {
        orderGoodMapper.updateById(orderGood);
        orderGood=orderGoodMapper.selectById(orderGood.getId());
        return Result.OK(getById(orderGood.getOrderId()));
    }

    @Override
    public Result<Order> createGoodOrder(Cart cart) {
        if(cart.getType()==1){
            cart.setGood(goodsMapper.selectById(cart.getGoodId()));
            if(cart.getGood()==null){
                return Result.error(ResponseState.GOOD_NOT_EXIST.getValue(),ResponseState.GOOD_NOT_EXIST.getMessage());
            }
            cart.getGood().setSpecification(goodsSpecificationService.specificationJsonInfo(cart.getSpecificationId()));
            if(cart.getGood().getSpecification()==null){
                return Result.error(ResponseState.SPECIFICATION_NOT_EXIST.getValue(),ResponseState.SPECIFICATION_NOT_EXIST.getMessage());
            }
            Double price=numPriceMapper.getPrice(cart.getNumber(),cart.getSpecificationId());
            if(price!=null&&price!=0){
                cart.getGood().getSpecification().setPrice(price);
            }
            cart.setPrice(cart.getGood().getSpecification().getPrice());
            BigDecimal goodsPrice= BigDecimal.valueOf(cart.getPrice());
            goodsPrice=goodsPrice.multiply(new BigDecimal(cart.getNumber()));
            List<Cart> cartList=new ArrayList<>();
            cartList.add(cart);
            Order order=new Order();
            order.setGoods(JSON.toJSONString(cartList));
            order.setGoodsPrice(goodsPrice.doubleValue());
            order.setFreightPrice(freightMapper.getFreightByPrice(order.getGoodsPrice()));
            BigDecimal totalPrice= BigDecimal.valueOf(order.getFreightPrice());
            totalPrice=totalPrice.add(goodsPrice);
            order.setTotalPrice(totalPrice.doubleValue());
            return Result.OK(order);
        }else {
            Order order=new Order();
            if(cart.getCartIds()==null||cart.getCartIds().size()==0){
                return Result.error(ResponseState.GOODS_IS_NULL.getValue(),ResponseState.GOODS_IS_NULL.getMessage());
            }
            CartList cartList=cartService.getByIds(cart.getCartIds());
            if(cartList.getCartList()==null||cartList.getCartList().size()==0){
                return Result.error(ResponseState.GOODS_IS_NULL.getValue(),ResponseState.GOODS_IS_NULL.getMessage());
            }
            order.setCart(cartList);
            order.setGoods(JSON.toJSONString(cartList.getCartList()));
            return Result.OK(order);
        }
    }

    /**
     * 提交订单
     */
    @Transactional
    @Override
    public Result<Order> addGoodOrder(GoodOrder goodOrder) {
        Order order=GoodOrder.getOrder(goodOrder);
        //直接购买
        if(goodOrder.getType()==1){
            Cart cart=GoodOrder.getCart(goodOrder);
            cart.setGood(goodsMapper.selectById(cart.getGoodId()));
            if(cart.getGood()==null){
                return Result.error(ResponseState.GOOD_NOT_EXIST.getValue(),ResponseState.GOOD_NOT_EXIST.getMessage());
            }
            cart.getGood().setSpecification(goodsSpecificationService.specificationJsonInfo(cart.getSpecificationId()));
            if(cart.getNumber()>cart.getGood().getSpecification().getStock()){
                return Result.error(ResponseState.STOCK_NOT_ENOUGH.getValue(),ResponseState.STOCK_NOT_ENOUGH.getMessage());
            }
            //判断是否超过单次订单最大购买数量
            if(cart.getGood().getSpecification().getMaxNumber()!=null){
                if(cart.getNumber()>cart.getGood().getSpecification().getMaxNumber()){
                    return Result.error(ResponseState.OVER_MAX_NUMBER.getValue(), ResponseState.OVER_MAX_NUMBER.getMessage());
                }
            }
            if(cart.getGood().getSpecification()==null){
                return Result.error(ResponseState.SPECIFICATION_NOT_EXIST.getValue(),ResponseState.SPECIFICATION_NOT_EXIST.getMessage());
            }
            Double price=numPriceMapper.getPrice(cart.getNumber(),cart.getSpecificationId());
            if(price!=null&&price!=0){
                cart.getGood().getSpecification().setPrice(price);
            }
            cart.setPrice(cart.getGood().getSpecification().getPrice());
            BigDecimal goodsPrice= BigDecimal.valueOf(cart.getPrice());
            List<Cart> cartList=new ArrayList<>();
            cartList.add(cart);
            order.setGoods(JSON.toJSONString(cartList));
            goodsPrice=goodsPrice.multiply(new BigDecimal(cart.getNumber()));
            order.setGoodsPrice(goodsPrice.doubleValue());
            order.setFreightPrice(freightMapper.getFreightByPrice(order.getGoodsPrice()));
            BigDecimal totalPrice= BigDecimal.valueOf(order.getFreightPrice());
            totalPrice=totalPrice.add(goodsPrice);
            order.setTotalPrice(totalPrice.doubleValue());
            order.setState(OrderState.START.getValue());
            order.setUserId(UserUtils.getLoginUserId());
            order.setOrderNumber(String.valueOf(new Date().getTime())+StringUtil.getSixNumer());
            orderMapper.insert(order);
            //减少库存
            stockService.reduceStock(cartList);
            return Result.OK(order);
        }else {
            if(goodOrder.getCartIds()==null||goodOrder.getCartIds().size()==0){
                return Result.error(ResponseState.GOODS_IS_NULL.getValue(),ResponseState.GOODS_IS_NULL.getMessage());
            }
            CartList cartList=cartService.getByIds(goodOrder.getCartIds());
            if(cartList.getCartList()==null||cartList.getCartList().size()==0){
                return Result.error(ResponseState.GOODS_IS_NULL.getValue(),ResponseState.GOODS_IS_NULL.getMessage());
            }
            order.setCart(cartList);
            order.setUserId(UserUtils.getLoginUserId());
            order.setOrderNumber(String.valueOf(new Date().getTime())+ StringUtil.getSixNumer());
            order.setState(OrderState.START.getValue());
            List<Cart> buyGoods=new ArrayList<>();
            for(Cart cart:cartList.getCartList()){
                if(cart.getLaterBuy()==1){
                    buyGoods.add(cart);
                    if(cart.getNumber()>cart.getGood().getSpecification().getStock()){
                        return Result.error(ResponseState.STOCK_NOT_ENOUGH.getValue(),ResponseState.STOCK_NOT_ENOUGH.getMessage());
                    }
                    if(cart.getGood().getSpecification().getMaxNumber()!=null){
                        if(cart.getNumber()>cart.getGood().getSpecification().getMaxNumber()){
                            return Result.error(ResponseState.OVER_MAX_NUMBER.getValue(), ResponseState.OVER_MAX_NUMBER.getMessage());
                        }
                    }
                }
            }
            order.setGoods(JSON.toJSONString(buyGoods));
            orderMapper.insert(order);
            if(goodOrder.getType()!=1&&goodOrder.getCartIds()!=null&&goodOrder.getCartIds().size()>0){
                cartService.batchDelete(goodOrder.getCartIds());
            }
            stockService.reduceStock(buyGoods);
            return Result.OK(getById(order.getId()));
        }


    }

    public static void main(String[] args) {
        System.out.println("");
    }

    @Transactional
    @Override
    public void autoFinish(String orderId) {
        Order oldOrder=orderMapper.selectById(orderId);
        if(oldOrder==null){
            return;
        }
        if(!oldOrder.getUserId().equals(UserUtils.getLoginUserId())){
            return;
        }
        if(oldOrder.getState()!=OrderState.GOOD_HAS_SEND.getValue()){
            return;
        }
        oldOrder.setFinishWay(2);
        oldOrder.setState(OrderState.ORDER_FINISH.getValue());
        oldOrder.setFinishAt(new Timestamp(new Date().getTime()));
        orderMapper.updateById(oldOrder);
        mailService.autoFinishOrder(oldOrder);
    }

    @Override
    public Result<Object> checkOrder(Order order) {
        Order oldOrder=orderMapper.selectById(order.getId());
        if(oldOrder==null){
            return Result.error(ResponseState.ORDER_NOT_EXIST.getValue(),ResponseState.ORDER_NOT_EXIST.getMessage());
        }
        if(oldOrder.getState()!=OrderState.CHECK.getValue()){
            return Result.error(ResponseState.OPERATION_HAI_FINISH.getValue(), ResponseState.OPERATION_HAI_FINISH.getMessage());
        }
        if(order.getState()==OrderState.ORDER_CANCEL.getValue()){
            return paymentService.refund(oldOrder);
        }else if(order.getState()==OrderState.COPY_SUCCESS.getValue()){

        }else{
            return Result.error(ResponseState.PARAM_IS_ERROR.getValue(),ResponseState.PARAM_IS_ERROR.getMessage());
        }
        orderMapper.updateById(order);
        return Result.OK();
    }


    @Override
    public Order getById(Serializable id) {
        return orderMapper.selectById(id);
    }



}